package gui;

import analysis.SysAnalysis;

import model.Element;
import model.SysPackage;
import model.SysRoot;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;

import visualization.ModelToGraph;

import edu.uci.ics.jung.algorithms.layout.AggregateLayout;
import edu.uci.ics.jung.algorithms.layout.TreeLayout;
import edu.uci.ics.jung.graph.DelegateForest;
import edu.uci.ics.jung.graph.DelegateTree;
import edu.uci.ics.jung.visualization.VisualizationViewer;

@SuppressWarnings("serial")
public class MainWindow extends JFrame implements GUIWindowInterface{

	private static MainWindow self = null;
	private static boolean window = false;
	private static VisualizationViewer<Element, Float> vv = null;
	private static boolean bvv = false;
	
	private String path = "bin";
	private JTextArea textArea = new JTextArea();
	private Container center;
	private SysRoot r = new SysRoot();
	private JPanel leftPanel = new JPanel();
	private int deltaX = 100;
	private int deltaY = 80;
	 
	/**constructs a new window (SingleTon Instance)*/
	public MainWindow(String name){
		super(name);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(false);
		//take a good visual for textArea :)
		textArea.setEditable(false);
		textArea.setBackground(Color.BLACK);
		textArea.setForeground(Color.GREEN);
		//==========================================================================setting the content of the frame 
		Container c = getContentPane();
		//make the textArea scrolleable
		JScrollPane scroll = new JScrollPane(textArea);
		scroll.setAutoscrolls(true);
		scroll.setPreferredSize(new Dimension(0,70));
		leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
		//button to choose the path to be analised
		JButton btn = new JButton("Choose path");
		btn.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				JFileChooser fc = new JFileChooser("."+File.separator+"..");
				fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
				if(fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
					//just show the selected path into the textArea
					path = fc.getSelectedFile().getAbsolutePath();
					textArea.append("You choose: " + path + "\n");
					int cont = JOptionPane.showConfirmDialog(null, "Analyse path: "+path+ " ?");
					if(cont == JOptionPane.OK_OPTION){
						MainWindow.this.analyse();
					}
				}
			}
		});
		btn.setSize(new Dimension(80,30));
		btn.setMaximumSize(new Dimension(80,30));
		leftPanel.add(btn);
		//button to analyse the path
		btn = new JButton("Analyse");
		btn.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				//here goes the magic...
				MainWindow.this.analyse();
			}});
		btn.setSize(new Dimension(80,30));
		btn.setMaximumSize(new Dimension(80,30));
		leftPanel.add(btn);
		leftPanel.setVisible(true);
		leftPanel.setSize(85, 170);
		c.add(leftPanel, BorderLayout.LINE_START);
		c.add(scroll,BorderLayout.PAGE_END);
		Container jl = new JLabel("");
		c.add(jl, BorderLayout.CENTER);
		setCenter(jl);
		pack();
		c.setVisible(true);
	}

	/**makes an initial and special analysis given the path*/
	public void analyse(){
		if(path==null){
			textArea.append("That is not a valid path\n");
		}
		else {
			textArea.append("Beginning analysis\n");
			SysRoot root = SysAnalysis.initialModel(path); // do the initial model
			r=root;
			DelegateTree<Element, Float> dt = new  DelegateTree<Element, Float>();
			dt.addVertex(root);
			dt = ModelToGraph.putAllChildren_SysRoot(dt, root);
			DelegateForest<Element, Float> df = new DelegateForest<Element, Float>(dt);
			VisualizationViewer<Element, Float> vv = new VisualizationViewer<Element, Float>(new TreeLayout<Element, Float>(df,deltaX,deltaY));
			setCenterPanel(vv);
			vv.updateUI();
			textArea.append(root.getPackages().toString()+"\n");
			makeGoodVisual(vv);
		}
	}

	public void setCenter(Container center) {
		this.center = center;
	}

	public Container getCenter() {
		return center;
	}

	public JTextArea getTextArea(){
		return this.textArea;
	}

	@SuppressWarnings("unchecked")
	public void setCenterPanel(Container pane){
		Container c = getContentPane();
		c.remove(getCenter()); 
		c.add(pane, BorderLayout.CENTER);
		setCenter(pane);
		if(pane instanceof VisualizationViewer){
			VisualizationViewer<Element, Float> vv = (VisualizationViewer<Element,Float>) pane;
			this.makeGoodVisual(vv);
			vv.updateUI();
		}
	}
	
	public void makeGoodVisual(VisualizationViewer<Element, Float>  vv){
		Utils.makeGoodVisual(vv, this);
	}
	
	public void makeMenuBar(VisualizationViewer<Element, Float>  vv){
		Utils.makeMenuBar(vv, this, r);
	}
	
	public static void main(String[] args) {
		
		try {			
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {}	
		System.out.println("Start: "+System.currentTimeMillis());
		Thread t0 = new Thread(){
			public void run(){
				MainWindow.self = new MainWindow("Main window");
				MainWindow.self.setExtendedState(MainWindow.MAXIMIZED_BOTH);
				MainWindow.window=true;
			}
		};		
		
		Thread t = new Thread(){
			@SuppressWarnings({ "rawtypes", "unchecked" })
			public void run(){
				DelegateTree t = new DelegateTree();
				SysRoot r = new SysRoot();
				r.add(new SysPackage("null"));
				t.addVertex(r);
				MainWindow.vv  = new VisualizationViewer(new AggregateLayout(new TreeLayout(t)));
				MainWindow.bvv=true;
			}
		};
		System.out.println("Starting threads: "+ (System.currentTimeMillis()));
		t0.start();
		t.start();
		System.out.println("Threads started: "+(System.currentTimeMillis()));
		try{
			while(!(MainWindow.bvv && MainWindow.window)){
				Thread.sleep(10);
			}
			MainWindow.self.setCenterPanel(vv);
			vv.updateUI();
		} catch(InterruptedException e){
			System.out.println("Error: "+(System.currentTimeMillis()));
			e.printStackTrace();
			MainWindow.self = null;
			MainWindow.vv = null;
			System.out.println("Starting single core: "+(System.currentTimeMillis()));
			System.err.println("Starting mainWindow in single core mode...");
			MainWindow m = new MainWindow("Main Window");
			m.setExtendedState(MAXIMIZED_BOTH);
		}
		System.out.println("Launching: "+(System.currentTimeMillis()));
		MainWindow.self.setVisible(true);
	}

	@Override
	public boolean rightClickEnabled() {
		return true;
	}
	
	@Override
	public JFrame getFrame() {
		return this;
	}

}